package com.cr.crsystem.system.controller;

import com.cr.crsystem.common.config.CarIdentificationConfig;
import com.cr.crsystem.common.config.ZnwdConfig;
import com.cr.crsystem.common.utils.Result;
import com.cr.crsystem.system.service.impl.ZnwdServiceImpl;
import com.cr.crsystem.system.vo.ImageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.RequestBody;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author su
 * @since 2022-06-21
 */
@CrossOrigin
@Api(tags = "图片管理")
@Slf4j
@RestController
@RequestMapping("/system/upload")
public class ImageController {
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private CarIdentificationConfig carIdentificationConfig;
    @Autowired
    private ZnwdServiceImpl znwdService;
    @Autowired
    private ZnwdConfig znwdConfig;

    public static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    @ApiOperation("上传用户图片")
    @PostMapping("/uploadUserImage")
    public Result<?> uploadUserImage(@RequestParam("file") MultipartFile file) {
        // 获取当前日期时间
        String dateTime = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))+"/";
        // 文件上传
        FileInfo fileInfo = null;  //将文件上传到对应地方
        try {
            fileInfo = fileStorageService.of(file)
                    .setPath(dateTime) //保存到相对路径下，为了方便管理，不需要可以不写
                    .upload();
        } catch (Exception e) {
            return Result.error("图片上传失败");
        }
        ImageVo imageVo = new ImageVo();
        imageVo.setUrl(fileInfo.getUrl());
        return Result.OK(imageVo);
    }

    @ApiOperation("上传车辆图片")
    @PostMapping("/uploadCarImage")
    public Result<?> uploadCarImage(@RequestParam("file") MultipartFile file) {
        // 获取当前日期时间
        String dateTime = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))+"/";
        // 文件上传
        FileInfo fileInfo = null;  //将文件上传到对应地方
        try {
            fileInfo = fileStorageService.of(file)
                    .setPath(dateTime) //保存到相对路径下，为了方便管理，不需要可以不写
                    .upload();
        } catch (Exception e) {
            return Result.error("图片上传失败");
        }
        ImageVo imageVo = new ImageVo();
        imageVo.setUrl(fileInfo.getUrl());
        // 识别车辆信息
        String result = null;
        try {
            result = getCarInfo(file);
            imageVo = parseCarInfo(result,imageVo);
        } catch (Exception e) {
            return Result.error("车辆识别失败");
        }
        return Result.OK(imageVo);
    }

    /**
     *   车辆识别，获取品牌、颜色等信息
     */
    public String getCarInfo(MultipartFile file) throws IOException {
        okhttp3.RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("image", "image.jpg", RequestBody.create(MediaType.parse("image/jpeg"), convertMultipartFileToBase64(file)))
                .build();
        Request request = new Request.Builder()
                .url(carIdentificationConfig.getUrl() + carIdentificationConfig.getAccessToken())
                .post(requestBody)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return response.body().string();
    }

    /**
     *    MultipartFile转换为图像数据，且进行Base64编码
     */
    public String convertMultipartFileToBase64(MultipartFile multipartFile) throws IOException {
        // 读取MultipartFile为BufferedImage
        InputStream inputStream = multipartFile.getInputStream();
        BufferedImage image = ImageIO.read(inputStream);

        // 将BufferedImage转换为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", baos); // 假设图像格式为JPEG
        byte[] imageBytes = baos.toByteArray();

        // 对字节数组进行Base64编码
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);

        baos.close();
        inputStream.close();
        return base64Image;
    }

    /**
     *   解析车辆识别结果
     */
    public ImageVo parseCarInfo(String carInfo,ImageVo imageVo) throws Exception {
        JSONObject jsonObject = new JSONObject(carInfo);
        JSONArray resultArray = jsonObject.getJSONArray("result");
        JSONObject carObject = resultArray.getJSONObject(0);
        // 获取品牌
        String brand = carObject.getString("name");
        // 获取颜色
        String colorResult = jsonObject.getString("color_result");
        imageVo.setBrand(brand);
        imageVo.setColor(colorResult);
        // 根据品牌、颜色获取座位数、价格、年份、详情等信息
        imageVo = getCarInfo(imageVo,brand,colorResult);
        return imageVo;
    }

    /**
     *      补齐车辆属性
     */
    public ImageVo getCarInfo(ImageVo imageVo,String carBrand,String carColor) throws Exception {
        String prompt = znwdService.getPrompt(carColor, carBrand);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType,znwdService.question(prompt));
        Request request = new Request.Builder()
                .url(znwdConfig.getUrl() + znwdConfig.getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        String result = response.body().string();
        // 处理结果
        JSONObject resultJsonObject = new JSONObject(new JSONObject(result).getString("result"));
        String year = resultJsonObject.getString("year");
        String price = resultJsonObject.getString("price");
        String seatingCapacity = resultJsonObject.getString("seatingCapacity");
        String detail = resultJsonObject.getString("detail");
        imageVo.setYear(year);
        imageVo.setPrice(price);
        imageVo.setSeatingCapacity(seatingCapacity);
        imageVo.setDetail(detail);
        return imageVo;
    }
}

